Week 4 of 16

Multi-Platform Comparison + Week 4 Review

Finish the comparison tool. See three AI-generated prompts side-by-side. Week 4 done.

Day 20 60 minutes Build

Day 20 of 80

Today's Goals

Yesterday you set up prompt_compare.py and wired the Claude API calls. Today you complete the tool by adding the display section, the save section, and error handling around each API call. Then you test it on a real shot.

Section What It Does
Display Print all three generated prompts side-by-side with clear separators
Save Ask which platforms to keep, filter results, append to prompts.json
Error handling Wrap each API call so one failure doesn't kill the whole comparison
Where We Left Off

Yesterday you built the generate_prompt() function and the loop that calls it for each platform, storing results in a results dictionary. Today you finish what happens after that loop runs.

The Foundation: Constants and the Generator Function

These should already be in your file from Day 19. Shown here for reference with full annotations:

prompt_compare.py — top of file Python
import anthropic
import json

# Re-use the same helper functions from prompt_manager_v2.py
PROMPTS_FILE = "prompts.json"
PLATFORMS    = ["Kling", "Runway", "Veo"]

# Anthropic client — reads ANTHROPIC_API_KEY from environment automatically
client = anthropic.Anthropic()

def load_prompts():
    try:
        with open(PROMPTS_FILE, "r") as f:
            return json.load(f)
    except FileNotFoundError:
        return []

def save_prompts(prompts):
    with open(PROMPTS_FILE, "w") as f:
        json.dump(prompts, f, indent=2)

def generate_prompt(shot, platform):
    """Call Claude to generate a prompt tuned for the given platform."""
    message = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=200,
        # system sets Claude's role — it stays in effect for the whole conversation
        system="You are an expert AI video prompt engineer.",
        messages=[{
            "role": "user",
            # f-string lets us inject shot and platform into the instruction
            "content": f"Write a {platform} AI video prompt for: {shot}. Match {platform}'s strengths. Under 75 words. Only the prompt."
        }]
    )
    # The response is a Message object; .content is a list of blocks;
    # [0].text gets the text from the first (and only) block
    return message.content[0].text

Adding Error Handling Around Each API Call

API calls can fail: the service might be temporarily down, you might hit a rate limit, or your key might have an issue. Without try/except, one failure crashes the entire script and you lose all three results. With it, you get two good prompts and one clear error message.

prompt_compare.py — generation loop with error handling Python
# Get the shot description from the user
shot = input("\nDescribe your shot: ").strip()

print("\nGenerating prompts — this may take a few seconds...\n")

# results will hold platform → generated prompt text (or error message)
results = {}

for platform in PLATFORMS:
    print(f"  Generating for {platform}...")
    try:
        # Call the API — this might take 1-3 seconds per platform
        results[platform] = generate_prompt(shot, platform)
    except Exception as e:
        # Catch ANY exception from the API call.
        # Store an error placeholder so display code can check for it.
        # The real error is available in 'e' if you need to debug.
        results[platform] = f"(Error: {e})"
        print(f"  Warning: {platform} failed — {e}")

The Display Section

After the loop, print a clean comparison table. The goal is to make it easy to read all three side-by-side and decide which platform's style fits the shot best.

prompt_compare.py — display section Python
# ── Display comparison ────────────────────────────────────────────────
print(f"\n{'=' * 50}")
print(f"  SHOT: {shot}")
print(f"{'=' * 50}\n")

# Loop through results dict — same order as PLATFORMS list
# because Python dicts preserve insertion order (Python 3.7+)
for platform, prompt in results.items():
    print(f"--- {platform} ---")
    print(f"{prompt}\n")

The Save Section

After reading the three prompts, the user decides what to keep. The save section handles three cases: save all, save specific platforms (comma-separated), or save nothing.

prompt_compare.py — save section Python
# ── Save options ──────────────────────────────────────────────────────
print("Save options: 'all', 'none', or platform names like 'Kling, Veo'")
choice = input("\nSave: ").strip().lower()

if choice == "all":
    # Save every result that isn't an error
    prompts = load_prompts()
    for platform, prompt in results.items():
        if not prompt.startswith("(Error"):
            prompts.append({"platform": platform, "shot": shot, "prompt": prompt})
    save_prompts(prompts)
    print("\n  All results saved to prompts.json\n")

elif choice == "none":
    # User just wanted to compare — nothing saved
    print("\n  Nothing saved.\n")

else:
    # Parse "kling, veo" → ["kling", "veo"]
    # .split(",") splits on commas; .strip() removes spaces around each name
    chosen = [c.strip().lower() for c in choice.split(",")]

    prompts     = load_prompts()
    saved_count = 0

    for platform, prompt in results.items():
        # Check: was this platform in the user's chosen list?
        # Was it a successful result (not an error)?
        if platform.lower() in chosen and not prompt.startswith("(Error"):
            prompts.append({"platform": platform, "shot": shot, "prompt": prompt})
            saved_count += 1

    save_prompts(prompts)
    print(f"\n  Saved {saved_count} prompt(s) to prompts.json\n")

Run It

Terminal
$ python prompt_compare.py

Describe your shot: Snowboarder launches off a kicker at sunset, slow motion

Generating prompts — this may take a few seconds...

  Generating for Kling...
  Generating for Runway...
  Generating for Veo...

==================================================
  SHOT: Snowboarder launches off a kicker at sunset, slow motion
==================================================

--- Kling ---
Ultra-slow motion snowboarder explodes off kicker ramp, golden-hour sun
behind, snow crystals suspended mid-air, limbs fully extended at peak,
shallow depth of field, 240fps feel, cinematic flare.

--- Runway ---
Dynamic slow-motion sequence: snowboarder launches from kicker, camera
locked below tracking upward, sunset silhouette against blazing orange sky,
snow spray catching light, smooth arc across frame.

--- Veo ---
High-speed aerial kicker jump at magic hour, snowboarder rotates against
vivid sunset gradient, powder trailing in slow-motion arc, photorealistic
skin and gear detail, immersive wide-angle perspective.

Save options: 'all', 'none', or platform names like 'Kling, Veo'

Save: Kling, Veo

  Saved 2 prompt(s) to prompts.json
This Is a Real Tool

What you just built is something you'd actually use in production. When you have a shot concept and you're deciding whether to send it to Kling, Runway, or Veo, you run prompt_compare.py, read the three platform-tuned outputs in 10 seconds, pick the one that fits, and save it. That's a real workflow. Compare this to writing three separate prompts by hand, adjusting for each platform's style, and deciding blind which one to try. You've automated the hard part.

Week 4 Milestone Check

What You Can Now Do

By the end of Week 4, you can:

End of Day Checklist

Tomorrow

Week 5 starts with a watch day on functions — going deeper on arguments, return values, default parameters, and how to design functions that compose cleanly. You'll use that knowledge all week as the tools grow more complex.